using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace ProjectCastamere
{
    /// <summary>
    /// This class is useful for objects that want to leave particles behind them as they move through the world
    /// This class keeps track of a moving object, remembering its previous position so it can calculate the velocity of the object
    /// It works out the perfect locations for creating particles at any frequency you specifiy, regardless of wether this is fast or slower
    /// that the game update rate
    /// </summary>
    public class ParticleEmitter
    {
        // the system
        ParticleSystem particleSystem;

        // the time between particles
        float timeBetweenParticles;

        // the previous position of the object
        Vector3 previousPosition;

        // the time left
        float timeLeftOver;

        // constructor
        public ParticleEmitter(ParticleSystem particleSystem, float particlesPerSecond, Vector3 initialPosition)
        {
            this.particleSystem = particleSystem;
            timeBetweenParticles = 1.0f / particlesPerSecond;
            previousPosition = initialPosition;
        }

        /// <summary>
        /// Updates the emitter, creating the appropriate number of particles
        /// in the correct locations
        /// </summary>
        /// <param name="gameTime"></param>
        /// <param name="newPosition"></param>
        public void Update(GameTime gameTime, Vector3 newPosition)
        {
            if (gameTime == null)
                throw new ArgumentNullException("gametime");

            // work out how much time has passed
            float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;

            if (elapsedTime > 0)
            {
                // work out how fast the object is moving
                Vector3 velocity = (newPosition - previousPosition) / elapsedTime;

                // If we had any time left over that we didnt use during the previous update
                // add that to the current time
                float timeToSpend = timeLeftOver + elapsedTime;

                // counter for looping over the time
                float currentTime = -timeLeftOver;

                // create particles as long as we have a big enough time interval
                while (timeToSpend > timeBetweenParticles)
                {
                    currentTime += timeBetweenParticles;
                    timeToSpend -= timeBetweenParticles;

                    // work out the optimal position using linear interpolation
                    // between old and current position
                    float mu = currentTime / elapsedTime;

                    Vector3 position = Vector3.Lerp(previousPosition, newPosition, mu);

                    // create particle
                    particleSystem.AddParticle(position, velocity);
                }
                // store any left over time
                timeLeftOver = timeToSpend;
            }
            // set the object position
            previousPosition = newPosition;
        }
    }
}
